package com.nativetalk.service.four.reserve;

import com.nativetalk.base.RetInfo;
import com.nativetalk.bean.SystemConfig;
import com.nativetalk.bean.course.TsNtCourseInfoDetail;
import com.nativetalk.bean.member.TdNtMember;
import com.nativetalk.bean.reserve.TdNtReserveInsert;
import com.nativetalk.bean.reserve.TdNtReserveTimeList;
import com.nativetalk.bean.teacher.TdNtTeacherResult;
import com.nativetalk.common.ValidationMessages;
import com.nativetalk.common.util.CommonUtil;
import com.nativetalk.common.util.MemcachedKey;
import com.nativetalk.common.util.MemcachedUtils;
import com.nativetalk.dao.*;
import com.nativetalk.dto.RecentlyAppointmentResponse;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by lizhun on 2016/11/1.
 * Modified by wangzheng on 2017/02/15
 */
@Service
public class FourReserveServiceImpl implements FourReserveService {
    private static Logger logger = Logger.getLogger(FourReserveServiceImpl.class);
    @Resource
    private TdNtReserveDao tdNtReserveDao;
    @Resource
    private TdNtReserveTimeDao tdNtReserveTimeDao;
    @Resource
    private TdNtLiveCourseHisDao tdNtLiveCourseHisDao;
    @Resource
    private TdNtTeachCourseDao tdNtTeachCourseDao;
    @Resource
    private TdNtMembSetmealDao tdNtMembSetmealDao;
    @Resource
    private TsNtCourseInfoDao tsNtCourseInfoDao;
    @Resource
    private TdNtMembCourseDao tdNtMembCourseDao;
    @Resource
    private TdNtMembCourseSizeDao tdNtMembCourseSizeDao;

    @Override
    public RetInfo search(TdNtMember tdNtMember) {
        String logInfo = this.getClass().getName() + ":coursesearch:";
        // 类路径+方法名
        logger.info("======" + logInfo + "begin======");
        RetInfo retInfo = new RetInfo();
        try {
            TdNtReserveInsert tdNtReserveInsert = tdNtReserveDao.findTdNtReserver(tdNtMember.getMemb_id());
            retInfo.setMark(ValidationMessages.getValue("MARKYES"));
            retInfo.setTip("获取列表成功");
            if (tdNtReserveInsert != null) {
                retInfo.setObj(0);
            } else {
                retInfo.setObj(1);
            }

        } catch (Exception e) {
            retInfo.setMark(ValidationMessages.getValue("MARKERROR"));
            retInfo.setTip(ValidationMessages.getValue("TIPERROR"));
            logger.error(e.getMessage(), e);
        }
        logger.info("======" + logInfo + "end======");
        return retInfo;
    }

    @Override
    public RetInfo findTeacherReserveTime(int tea_id, TdNtMember tdNtMember, String date, int version, String client_type) {
        String logInfo = this.getClass().getName() + ":findTeacherReserveTime:";
        // 类路径+方法名
        logger.info("======" + logInfo + "begin======");
        RetInfo retInfo = new RetInfo();
        try {
            Map<String, SystemConfig> systemConfigMap = (Map<String, SystemConfig>) MemcachedUtils.get(MemcachedKey.systemConfig);
            SystemConfig systemConfig = systemConfigMap.get("systemAppointmentTimeThreshold");
            int systemAppointmentTimeThreshold = Integer.parseInt(systemConfig.getValue());
            logger.info("\n\n\nsystemAppointmentTimeThreshold=" + systemAppointmentTimeThreshold + "\n\n\n");

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Map<String, Object> params = new HashMap<>();
            params.put("tea_id", tea_id);
            int week = CommonUtil.getWeekday(sdf.format(new Date(Long.valueOf(date))));

            Map<String, Object> map = new HashMap<>();

            // 第一步：查询学生可以预约的课程列表（符合以下2个条件才能预约：1.老师开设的课程和学生购买的课程有交集，2.交集课程中可预约课时>0）
            // 1.1 老师开启的课程
            List<TsNtCourseInfoDetail> teacherOpenCourse = tsNtCourseInfoDao.findTeacherOpenCourse(tea_id);//老师已开通的课程集合

            // 1.2 查询学生购买的可以预约的课程: 1.有效课程，2.可预约课时数>0
            List<TsNtCourseInfoDetail> studentBookableCourseList = tsNtCourseInfoDao.findBookableCourseInfo(tdNtMember.getMemb_id());

            // 1.3 求交集：学生已购买的课程与老师已开通的课程（学生可以预约这个老师的课程列表）
            List<TsNtCourseInfoDetail> bookableCourseListForTeacher = new ArrayList<>();//交集课程List
            if (0 < teacherOpenCourse.size()) {
                List<Integer> teacherOpenCourseIds = new ArrayList<>();//老师已开通的课程id集合
                for (int i = 0; i < teacherOpenCourse.size(); i++) {
                    teacherOpenCourseIds.add(teacherOpenCourse.get(i).getCou_id());
                }
                for (int j = 0; j < studentBookableCourseList.size(); j++) {
                    if (teacherOpenCourseIds.indexOf(studentBookableCourseList.get(j).getCou_id()) > -1) {
                        bookableCourseListForTeacher.add(studentBookableCourseList.get(j));
                    }
                }
            }
            map.put("courseSize", bookableCourseListForTeacher.size());//可以预约的课程数
            map.put("courses", bookableCourseListForTeacher); // 可以预约的课程列表

            // 第二步：查询老师7天内可以预约的时间
            List<TdNtReserveTimeList> tdNtReserveTimeWeekLists = new ArrayList<>();
            Map<Integer, List<TdNtReserveTimeList>> tdNtReserveTimeWeekMap = new HashMap<>();
            //获取包括今天的7天的预约信息
            for (int i = 0; i < 7; i++) {
                Date reserve_date = CommonUtil.addData(new Date(Long.valueOf(date)), i);
                params.put("reserve_date", reserve_date);
                //1天的预约时间列表
                List<TdNtReserveTimeList> tdNtReserveTimeLists = tdNtReserveTimeDao.findTdNtReserveTimeList(params);
                if (null != tdNtReserveTimeLists) {
                    Iterator<TdNtReserveTimeList> iter = tdNtReserveTimeLists.iterator();
                    while (iter.hasNext()) {
                        TdNtReserveTimeList tdNtReserveTimeList = iter.next();
                        //i表示比当前时间大几天
                        Timestamp reserve_time = new Timestamp(tdNtReserveTimeList.getDate().getTime());
                        /**
                         * 查找该老师是否有冲突时间的预约课或直播课
                         */
                        Map<String, Object> map1 = new HashMap<>();
                        map1.put("tea_id", tea_id);
                        map1.put("start_time", reserve_time);
                        //结束时间为开始时间加上50分钟
                        map1.put("end_time", new Timestamp(reserve_time.getTime() + 3000000L));
                        TdNtReserveInsert tdNtReserveInsert = tdNtReserveDao.findTdNtReserverConflict(map1);
                        if (tdNtReserveInsert != null) {
                            tdNtReserveTimeList.setIs_valid(2);//已被约
                        }
                        /**
                         * 老师开通时间周几设置
                         */
                        tdNtReserveTimeList.setReserve_week(CommonUtil.getWeekday(sdf.format(tdNtReserveTimeList.getDate())));

                        //当天老师开通的时间列表
                        if (0 == i) {
                            Timestamp time = new Timestamp(Long.valueOf(date));
                            //判断预约请求的时间(当是否大于等于老师开通的时间或者老师开通的时间超过请求的时间没有大于等于60分钟前时间)
                            //没有的话要去掉
                            if (reserve_time.getTime() < time.getTime() + systemAppointmentTimeThreshold * 1000) {
                                iter.remove();
                            }
                        }
                    }
                }
                tdNtReserveTimeWeekLists.addAll(tdNtReserveTimeLists);
                tdNtReserveTimeWeekMap.put(week, tdNtReserveTimeLists);
                week++;
                if (week > 7) {
                    week = 1;
                }
            }

            if ("1".equals(client_type)) {
                map.put("weekReservetime", tdNtReserveTimeWeekLists);
            } else {
                map.put("weekReservetime", tdNtReserveTimeWeekMap);
            }

            retInfo.setMark(ValidationMessages.getValue("MARKYES"));
            retInfo.setTip("获取数据成功");
            retInfo.setObj(map);
        } catch (Exception e) {
            retInfo.setMark(ValidationMessages.getValue("MARKERROR"));
            retInfo.setTip(ValidationMessages.getValue("TIPERROR"));
            logger.error(e.getMessage(), e);
        }
        logger.info("======" + logInfo + "end======");
        return retInfo;
    }

    public RecentlyAppointmentResponse findRecentlyAppointment(TdNtTeacherResult teacher) {
        RecentlyAppointmentResponse response = tdNtReserveDao.findRecentlyAppointment(teacher.getTea_id());
        return response;
    }
}
